#pragma once
#include "enums.h"
#include <memory>
#include "Helper.h"

namespace DXBase
{
	namespace DWrite
	{
		// TODO IDWriteCollection
		[Windows::Foundation::Metadata::WebHostHidden]
		public ref class TextFormat sealed
		{
		private:
			Microsoft::WRL::ComPtr<IDWriteTextFormat> mTextFmt;

			// destruct IDWriteTextFormat
			Platform::String^ fontFamilyName;
			DWRITE_FONT_WEIGHT fontWeight;
			DWRITE_FONT_STYLE fontStyle;
			DWRITE_FONT_STRETCH fontStretch;
			FLOAT fontSize;
			Platform::String^  localeName;

			// update IDWriteTextFormat
			DWRITE_FLOW_DIRECTION flowDirection;
			float incrementalTabStop;
			DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment;
			DWRITE_READING_DIRECTION readingDirection;
			DWRITE_TEXT_ALIGNMENT textAlignment;
			DWRITE_WORD_WRAPPING wordWrapping;

		internal:
			Microsoft::WRL::ComPtr<IDWriteTextFormat> GetNativeFormat();

		public:
			TextFormat();

			property Platform::String^ FontFamilyName
			{
				Platform::String^ get() { return fontFamilyName; }
				void set(Platform::String^ value)
				{
					fontFamilyName = value;
					mTextFmt = nullptr;
				}
			}
			property Platform::String^ LocaleName
			{
				Platform::String^ get() { return localeName; }
				void set(Platform::String^ value)
				{
					localeName = value;
					mTextFmt = nullptr;
				}
			}
			property float FontSize
			{
				float get() { return fontSize; }
				void set(float value)
				{
					fontSize = value;
					mTextFmt = nullptr;
				}
			}
			property FONT_STYLE FontStyle
			{
				FONT_STYLE get() { return fromD2D(fontStyle); }
				void set(FONT_STYLE value)
				{
					fontStyle = makeD2D(value);
					mTextFmt = nullptr;
				}
			}
			property FONT_STRETCH FontStretch
			{
				FONT_STRETCH get() { return fromD2D(fontStretch); }
				void set(FONT_STRETCH value)
				{
					fontStretch = makeD2D(value);
					mTextFmt = nullptr;
				}
			}
			property FONT_WEIGHT FontWeight
			{
				FONT_WEIGHT get() { return fromD2D(fontWeight); }
				void set(FONT_WEIGHT value)
				{
					fontWeight = makeD2D(value);
					mTextFmt = nullptr;
				}
			}
			property FLOW_DIRECTION FlowDirection
			{
				FLOW_DIRECTION get() { return static_cast<FLOW_DIRECTION>(flowDirection); }
				void set(FLOW_DIRECTION value)
				{
					if (mTextFmt)
					{
						auto nvalue = static_cast<DWRITE_FLOW_DIRECTION>(value);
						HR2Ex(mTextFmt->SetFlowDirection(nvalue));
						flowDirection = nvalue;
					}
					else
					{
						flowDirection = static_cast<DWRITE_FLOW_DIRECTION>(value);
					}
				}
			}
			property float IncrementalTabStop
			{
				float get() { return incrementalTabStop; }
				void set(float value)
				{
					if (mTextFmt)
					{
						HR2Ex(mTextFmt->SetIncrementalTabStop(value));
						incrementalTabStop = value;
					}
					else
					{
						incrementalTabStop = value;
					}
				}
			}
			// TODO LineSpacing
			property PARAGRAPH_ALIGNMENT ParagraphAlignment
			{
				PARAGRAPH_ALIGNMENT get() { return static_cast<PARAGRAPH_ALIGNMENT>(paragraphAlignment); }
				void set(PARAGRAPH_ALIGNMENT value)
				{
					if (mTextFmt)
					{
						auto nvalue = static_cast<DWRITE_PARAGRAPH_ALIGNMENT>(value);
						HR2Ex(mTextFmt->SetParagraphAlignment(nvalue));
						paragraphAlignment = nvalue;
					}
					else
					{
						paragraphAlignment = static_cast<DWRITE_PARAGRAPH_ALIGNMENT>(value);
					}
				}
			}
			property READING_DIRECTION ReadingDirection
			{
				READING_DIRECTION get() { return static_cast<READING_DIRECTION>(readingDirection); }
				void set(READING_DIRECTION value)
				{
					if (mTextFmt)
					{
						auto nvalue = static_cast<DWRITE_READING_DIRECTION>(value);
						HR2Ex(mTextFmt->SetReadingDirection(nvalue));
						readingDirection = nvalue;
					}
					else
					{
						readingDirection = static_cast<DWRITE_READING_DIRECTION>(value);
					}
				}
			}
			property TEXT_ALIGNMENT TextAlignment
			{
				TEXT_ALIGNMENT get() { return static_cast<TEXT_ALIGNMENT>(textAlignment); }
				void set(TEXT_ALIGNMENT value)
				{
					if (mTextFmt)
					{
						auto nvalue = static_cast<DWRITE_TEXT_ALIGNMENT>(value);
						HR2Ex(mTextFmt->SetTextAlignment(nvalue));
						textAlignment = nvalue;
					}
					else
					{
						textAlignment = static_cast<DWRITE_TEXT_ALIGNMENT>(value);
					}
				}
			}
			// TOD Trimming
			property WORD_WRAPPING WordWrapping
			{
				WORD_WRAPPING get() { return static_cast<WORD_WRAPPING>(wordWrapping); }
				void set(WORD_WRAPPING value)
				{
					if (mTextFmt)
					{
						auto nvalue = static_cast<DWRITE_WORD_WRAPPING>(value);
						HR2Ex(mTextFmt->SetWordWrapping(nvalue));
						wordWrapping = nvalue;
					}
					else
					{
						wordWrapping = static_cast<DWRITE_WORD_WRAPPING>(value);
					}
				}
			}
		};
	}
}